<template>
  <div
    class="w-full py-[20px] my-[50px] h-max"
    v-if="gamType === GamTypeEnum.手动广告"
  >
    <div class="text-center text-white font-semibold">Advertisement</div>
    <div
      :id="gamDefineSlot"
      class="w-full flex-center min-h-[300px]"
      :gamType="gamType"
      :gamDefineSlot="gamDefineSlot"
    ></div>
  </div>
</template>

<script lang="ts" setup>
import { useGA } from "~/composables/useGA";

const { channel = "" } = useRoute().query;
const {
  gamDefineSlot = "",
  gamType = GamTypeEnum.手动广告,
  position = AdPositionEnum.下,
} = defineProps<{
  /** GAM广告配置 */
  gamDefineSlot?: string;
  /**
   * 广告类型
   * @default 手动广告
   */
  gamType?: GamTypeEnum;
  /**
   * 锚定广告的位置
   * @default 'bottom'
   */
  position?: AdPositionEnum;
}>();
const { trackEvent } = useGA();

onMounted(() => {
  if (!gamDefineSlot) return;
  switch (gamType) {
    case GamTypeEnum.自动插屏广告: {
      initGamInterstitialAd();
      break;
    }
    case GamTypeEnum.自动锚定广告: {
      initGamAnchor();
      break;
    }
    case GamTypeEnum.手动广告: {
      const dom = document.getElementById(gamDefineSlot);
      const observer = new IntersectionObserver(
        (entries) => {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              trackEvent({
                eventName: "GAM_AD_View",
                params: {
                  slot: gamDefineSlot,
                },
              });
              initGam();
              observer.disconnect();
            }
          });
        },
        {
          threshold: 0,
        },
      );
      dom && observer.observe(dom);
      break;
    }
    case GamTypeEnum.手动激励广告: {
      initGamRewardedAd();
      break;
    }
    default: {
      break;
    }
  }
});

/** GAM手动广告 */
const initGam = () => {
  window.googletag = window.googletag || { cmd: [] };
  googletag.cmd.push(() => {
    /** 渲染广告 */
    googletag
      .defineSlot(gamDefineSlot, ["fluid", [window.innerWidth - 40, 300]], gamDefineSlot)
      ?.addService(googletag.pubads());
    if (gamDefineSlot) {
      /** 监听广告加载状态 */
      googletag.pubads().addEventListener("slotRenderEnded", (event) => {
        const { slot, isEmpty } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot)) {
          trackEvent({
            eventName: isEmpty ? "GAM_AD_Show_Fail" : "GAM_AD_Show",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      channel && googletag.pubads().setTargeting("afc_channel", channel as string);
    }
    googletag.enableServices();
    googletag.display(gamDefineSlot);
  });
};

/** GAM自动锚定广告 */
const initGamAnchor = () => {
  window.googletag = window.googletag || { cmd: [] };
  googletag.cmd.push(() => {
    /** 监听广告加载状态 */
    const anchorSlot = googletag.defineOutOfPageSlot(
      gamDefineSlot,
      position === AdPositionEnum.下
        ? googletag.enums.OutOfPageFormat.BOTTOM_ANCHOR
        : googletag.enums.OutOfPageFormat.TOP_ANCHOR,
    );
    if (anchorSlot) {
      anchorSlot.addService(googletag.pubads());
      // GAM自动锚定广告展示失败上报
      googletag.pubads().addEventListener("slotRenderEnded", (event) => {
        const { slot, isEmpty } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot) && isEmpty) {
          trackAutoAd({
            isEmpty: true,
            slot: gamDefineSlot,
          });
          trackEvent({
            eventName: "GAM_Anc_AD_Show_Fail_Auto",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      // GAM自动锚定广告展示到用户可视界面时上报
      googletag.pubads().addEventListener("impressionViewable", (event) => {
        const { slot } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot)) {
          trackAutoAd({
            isEmpty: false,
            slot: gamDefineSlot,
          });
          trackEvent({
            eventName: "GAM_Anc_AD_Show_Auto",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      channel && googletag.pubads().setTargeting("afc_channel", channel as string);
    }
    googletag.pubads().enableSingleRequest();
    googletag.enableServices();
    anchorSlot && googletag.display(anchorSlot);
  });
};

/** GAM自动插屏广告 */
const initGamInterstitialAd = () => {
  window.googletag = window.googletag || { cmd: [] };
  googletag.cmd.push(() => {
    /** 监听广告加载状态 */
    const anchorSlot = googletag.defineOutOfPageSlot(
      gamDefineSlot,
      googletag.enums.OutOfPageFormat.INTERSTITIAL,
    );
    if (anchorSlot) {
      anchorSlot.addService(googletag.pubads());
      // GAM自动插屏广告加载失败上报
      googletag.pubads().addEventListener("slotRenderEnded", (event) => {
        const { slot, isEmpty } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot) && isEmpty) {
          trackAutoAd({
            isEmpty: true,
            slot: gamDefineSlot,
          });
          trackEvent({
            eventName: "GAM_Inter_AD_Show_Fail_Auto",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      // GAM自动插屏广告真正展示到用户可视界面上报
      googletag.pubads().addEventListener("impressionViewable", (event) => {
        const { slot } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot)) {
          trackAutoAd({
            isEmpty: false,
            slot: gamDefineSlot,
          });
          trackEvent({
            eventName: "GAM_Inter_AD_Show_Auto",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      channel && googletag.pubads().setTargeting("afc_channel", channel as string);
    }
    googletag.pubads().enableSingleRequest();
    googletag.enableServices();
    anchorSlot && googletag.display(anchorSlot);
  });
};

/** GAM手动激励广告 */
const initGamRewardedAd = () => {
  window.googletag = window.googletag || { cmd: [] };
  googletag.cmd.push(() => {
    /** 监听广告加载状态 */
    const rewardedSlot = googletag.defineOutOfPageSlot(
      gamDefineSlot,
      googletag.enums.OutOfPageFormat.REWARDED,
    );
    if (rewardedSlot) {
      rewardedSlot.addService(googletag.pubads());
      // GAM手动激励广告加载准备成功，待点击事件触发展示广告
      googletag.pubads().addEventListener("rewardedSlotReady", (event) => {
        const btnPlay = document.getElementById("btnPlay");
        btnPlay?.addEventListener("click", () => {
          event.makeRewardedVisible();
        });
      });
      // GAM手动激励广告加载完成后，点击事件上报加载失败
      googletag.pubads().addEventListener("slotRenderEnded", (event) => {
        const { isEmpty, slot } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot) && isEmpty) {
          const btnPlay = document.getElementById("btnPlay");
          btnPlay?.addEventListener("click", () => {
            trackEvent({
              eventName: "GAM_MRV_Show_Fail",
              params: {
                slot: gamDefineSlot,
              },
            });
          });
        }
      });
      // GAM手动激励广告真正展示到用户可视界面上报
      googletag.pubads().addEventListener("impressionViewable", (event) => {
        const { slot } = event;
        const slotId = slot.getSlotElementId();
        if (slotId.includes(gamDefineSlot)) {
          trackEvent({
            eventName: "GAM_MRV_Show",
            params: {
              slot: gamDefineSlot,
            },
          });
        }
      });
      channel && googletag.pubads().setTargeting("afc_channel", channel as string);
    }
    googletag.pubads().enableSingleRequest();
    googletag.enableServices();
    rewardedSlot && googletag.display(rewardedSlot);
  });
};

/**
 * 统一渲染GAM自动广告埋点
 * @param trackAutoAd
 */
const trackAutoAd = (trackAutoAd: TrackAutoAdType) => {
  const { isEmpty, slot } = trackAutoAd;
  trackEvent({
    eventName: isEmpty ? "GAM_AD_Show_Fail_Auto" : "GAM_AD_Show_Auto",
    params: {
      slot,
    },
  });
};
</script>

<style scoped></style>
